package com.naiterui.ehp.ps.sms.factory;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;

import com.naiterui.ehp.bp.utils.encypt.MD5;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.ps.sms.exception.ExceptionCodes;
import com.naiterui.ehp.ps.sms.exception.SmsBusinessException;
import com.naiterui.ehp.ps.sms.utils.HttpRequestUtils;
import com.naiterui.ehp.ps.sms.utils.constants.SmsConstants;

import lombok.extern.slf4j.Slf4j;

/**
 * 梦网短信平台API
 *
 * @author
 * @since 1.0.0
 */
@Slf4j
public class MontnetApi {
    private static final String API_BASE_URL = ConfigUtil.getString(SmsConstants.API_MONTNET_BASE_URL); // 梦网API基础路径
    private static final String API_SINGLE_SEND_URL = API_BASE_URL + "/single_send";// 单条发送请求url
    private static final String API_BATCH_STATUS_REPORT_URL = API_BASE_URL + "/get_rpt";// 批量获取状态报告
    private static final String USERID = ConfigUtil.getString(SmsConstants.API_MONTNET_USERID);// 梦网用户名
    private static final String PASSWORD = ConfigUtil.getString(SmsConstants.API_MONTNET_PASSWORD);// 用户密码
    private static final String ENCRYPT_FIXED_STR = "00000000";// 鉴权固定字符串
    private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("MMddHHmmss");
    private static final int MAX_REPORT_COUNT = 100;// 批量获取状态报告返回最大记录数

    /**
     * 单条发送短信
     * MontnetApi.siggleSend()
     *
     * @param phone
     * @param content
     *
     * @return
     *
     * @Author
     * @Date 2017年7月26日
     * @since 1.0.0
     */
    public static String siggleSend(String phone, String businessId, String content) throws SmsBusinessException {
        StringBuffer params = new StringBuffer();
        generateCommParamsStr(params);// 获取接口公共参数
        params.append("&mobile=").append(phone);// 接收的用户手机号码
        String encodeMessage = "";
        try {
            encodeMessage = URLEncoder.encode(content, "GBK");
        } catch (UnsupportedEncodingException e) {
            log.error("调用梦网发送短信接口,参数转码失败,phone:{},content:{}", phone, content, e);
            throw new SmsBusinessException(ExceptionCodes.PARAM_ERROR, e);
        }
        params.append("&content=").append(encodeMessage);// 短信内容
        params.append("&SvrType=").append(businessId);

        // 请求header信息
        Map<String, String> headers = getBaseHeader();
        // 调用梦网API接口
        log.info("调用梦网发送短信接口: url : {}, params : {}, header : {}", API_SINGLE_SEND_URL, params.toString(), headers);
        String result = HttpRequestUtils.doPostBasicAndHeader(API_SINGLE_SEND_URL, params.toString(), headers);
        return result;
    }

    /**
     * 批量获取状态报告
     * MontnetApi.getBatchReport()
     *
     * @return
     *
     * @Author
     * @Date 2017年7月28日
     * @since 1.0.0
     */
    public static String getBatchReport() {
        StringBuffer params = new StringBuffer();
        generateCommParamsStr(params);// 获取接口公共参数
        params.append("&retsize=").append(String.valueOf(MAX_REPORT_COUNT));
        // 请求header信息
        Map<String, String> headers = getBaseHeader();
        // 调用梦网API接口
        log.info("调用梦网获取状态报告接口: url : {}, params : {}, header : {}", API_BATCH_STATUS_REPORT_URL, params.toString(), headers);
        String result = HttpRequestUtils.doPostBasicAndHeader(API_BATCH_STATUS_REPORT_URL, params.toString(), headers);

        return result;
    }

    /**
     * 加密密码，用于接口鉴权
     * MontnetApi.encryptPwd()
     *
     * @param timestamp
     *
     * @return
     *
     * @Author
     * @Date 2017年7月26日
     * @since 1.0.0
     */
    private static String encryptPwd(String timestamp) {
        // 加密后的字符串
        String encryptPwd = null;
        StringBuffer pwdBuffer = new StringBuffer();
        pwdBuffer.append(USERID.toUpperCase()).append(ENCRYPT_FIXED_STR).append(PASSWORD).append(timestamp);
        // 对密码进行加密
        encryptPwd = MD5.md5(pwdBuffer.toString());
        // 返回加密字符串
        return encryptPwd;
    }

    /**
     * 生成API统一参数
     * MontnetApi.generateCommParamsStr()
     *
     * @param params
     *
     * @Author
     * @Date 2017年7月28日
     * @since 1.0.0
     */
    private static void generateCommParamsStr(StringBuffer params) {
        // 设置时间戳
        String timestamp = DATE_FORMATTER.format(Calendar.getInstance().getTime());
        String encryptedPwd = encryptPwd(timestamp);
        params.append("userid=").append(USERID.toUpperCase());// 用户ID
        params.append("&pwd=").append(encryptedPwd);// 加密后的密码
        params.append("&timestamp=").append(timestamp);// 时间戳
    }

    /**
     * 获取公共请求头
     * MontnetApi.getBaseHeader()
     *
     * @return
     *
     * @Author
     * @Date 2017年8月2日
     * @since 1.0.0
     */
    private static Map<String, String> getBaseHeader() {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        return headers;
    }

}
